原始题目:剑指 Offer 26. 树的子结构 (opens new window)
解题思路:
如果 是 的子结构,则 的根节点可能是 中的任意一节点,因此需要遍历A 的所有节点 ,判断 B 是否是 的子结构。
- 先序遍历 的每个节点 ;
- 如果 和 都为 ,根据题意直接返回 。
- 判断以 为根节点的树是否包含树 。
- 如果 为 ,那么检查完毕,返回 。
- 如果 为 或者 、 的值不相等,那么 肯定不是子结构,返回 。
- 检查 的左子树 是否为 的左子树的子结构,并且检查 的右子树是否为 的右子树的子结构。
代码:
public boolean isSubStructure(TreeNode A, TreeNode B) {
return (A != null && B != null)
&& (recur(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B));
}
private boolean recur(TreeNode nA, TreeNode B) {
if (B == null) {
return true;
}
if (nA == null || nA.val != B.val) {
return false;
}
return recur(nA.left, B.left) && recur(nA.right, B.right);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
复杂度分析
时间复杂度:其中 和 分别为 树和 树的数量。先序遍历 树占用 ,每次调用 recur 最多占用 。
空间复杂度:当树 和树 都退化为链表时,递归调用深度最大。当 时,遍历树 与递归判断的总递归深度为 ;当 时,最差情况为遍历至树 叶子节点,此时总递归深度为 。